package com.keitaitoys.plugin;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ServiceLoader;

public class BasicPluginService implements PluginService {

	//////////////////////////////////////////////////////////////////////
	// Description ///////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////
	// Consts ////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////
	// Variables /////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	private static BasicPluginService basicPluginService;
	private final ServiceLoader<Plugin> serviceLoader;
	
	//////////////////////////////////////////////////////////////////////
	// Constructor ///////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	private BasicPluginService() {
		
		serviceLoader = ServiceLoader.load(Plugin.class);
	}
	
	//////////////////////////////////////////////////////////////////////
	// Functions /////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	public static synchronized BasicPluginService getInstance() {
		
		if(basicPluginService == null) {
			basicPluginService = new BasicPluginService();
		}
		
		return basicPluginService;
	}
	
	//////////////////////////////////////////////////////////////////////
	// Functions /////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	public ArrayList<Plugin> getPlugins() {

		return getPlugins(Plugin.class);
	}

	//////////////////////////////////////////////////////////////////////
	// Functions /////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	public <T extends Plugin> ArrayList<T> getPlugins(Class<T> pluginClass) {
		
		ArrayList<T> plugins = new ArrayList<T>();
		
		Iterator<Plugin> pluginIterator = serviceLoader.iterator();
			
		while(pluginIterator.hasNext()) {

			Plugin plugin = pluginIterator.next(); 
				
			if(pluginClass.isAssignableFrom(plugin.getClass())) {
				plugins.add(pluginClass.cast(plugin));
			}
		}
		
		return plugins;
	}
}
